import 'package:flutter/material.dart';
import 'package:hktk_app/util/view_util.dart';

/// 章节缩进对应样式
class ChapterIndentDecoration extends Decoration {
  /// 线条颜色
  final Color? color;

  /// 线条宽度
  final double? white;

  /// 每根虚线的长度
  final double? dashedLength;

  /// 每根虚线的间隔
  final double? dashedGap;

  const ChapterIndentDecoration({
    this.color,
    this.white,
    this.dashedLength,
    this.dashedGap,
  });

  @override
  BoxPainter createBoxPainter([VoidCallback? onChanged]) {
    return _ChapterIndentPainter(
      chapterIndentDecoration: this,
      lineColor: color,
      lineWhite: white,
      dashedLength: dashedLength,
      dashedGap: dashedGap,
    );
  }
}

class _ChapterIndentPainter extends BoxPainter {
  final ChapterIndentDecoration chapterIndentDecoration;

  /// 线条颜色
  final Color? lineColor;

  /// 线条宽度
  final double? lineWhite;

  /// 每根虚线的长度
  final double? dashedLength;

  /// 每根虚线的间隔
  final double? dashedGap;

  _ChapterIndentPainter({
    required this.chapterIndentDecoration,
    this.lineColor,
    this.lineWhite,
    this.dashedLength,
    this.dashedGap,
  });

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    var size = configuration.size!;

    double startX = offset.dx;
    double startY = offset.dy;
    double bottomY = startY + size.height;

    //画笔
    Paint paint = Paint()
      ..color = lineColor ?? colorGrey3
      ..strokeWidth = lineWhite ?? 2
      ..style = PaintingStyle.stroke;

    // 路径
    Path path = Path();
    path.moveTo(startX, startY);
    path.lineTo(startX, bottomY);
    // 将路径解析为虚线
    Path path1 = _convertDashedPath(
      path: path,
      dashedLength: dashedLength ?? 4,
      dashedGap: dashedGap ?? 2,
    );

    // 绘画
    canvas.drawPath(path1, paint);
  }

  /// 将实现路径专为虚线路径，
  /// dashedLength：每根虚线的长度，
  /// dashedGap：每根虚线的间隔，
  Path _convertDashedPath({
    required Path path,
    required double dashedLength,
    required double dashedGap,
  }) {
    Path dashedPath = Path();

    // 虚线Path转换的核心，需要理解下面两个代码：
    // 1、path.computeMetrics()，获取Path的轮廓。
    // 2、metric.extractPath(distance, distance +dottedLength)，从轮廓中获取裁剪出子Path。
    for (var metric in path.computeMetrics()) {
      double distance = 0;
      bool isDrawDotted = true;
      while (distance < metric.length) {
        if (isDrawDotted) {
          dashedPath.addPath(
              metric.extractPath(distance, distance + dashedLength),
              Offset.zero);
          distance += dashedLength;
        } else {
          distance += dashedGap;
        }
        isDrawDotted = !isDrawDotted;
      }
    }

    return dashedPath;
  }
}
